﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Infragistics.Win.UltraWinGrid;
using Litografia.BusinessComponents;
using Litografia.BusinessEntities;
using Litografia.UI.UserControls;
using SIL.FieldWorks.Common.Controls;

namespace Litografia.UI
{
    [Flags]
    public enum ToolBarButtons
    {
        None = 0,
        Save = 1,
        Edit = 2,
        Delete = 4,
        Clear = 8,
        New = 16,
        Search = 32,
        Preview = 64,
        Print = 128,
        Approve = 256,
        Close = 512,
        InProcess = 1024
    }

    public partial class BaseForm : Form
    {
        #region Declarations

        private static Stream imageStream;
        private static Assembly assembly;

        private const string NamespaceName = "Litografia.UI";
        protected const string GridGroupBoxText = "Arrastre una columna aquí para agrupar por esa columna";

        #endregion

        #region Constructors

        public BaseForm()
        {
            InitializeComponent();
            assembly = Assembly.GetExecutingAssembly();
        }

        #endregion

        #region Event Handlers

        private void BaseForm_Load(object sender, EventArgs e)
        {
            toolStrip.CausesValidation = true;
        }

        #endregion

        #region Methods: Public

        public static void ToggleButton(ToolStrip toolStrip, ToolBarButtons button, bool enabled)
        {
            switch (button)
            {
                case ToolBarButtons.Preview:
                    {
                        toolStrip.Items["VistaPreliminar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Save:
                    {
                        toolStrip.Items["Guardar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Delete:
                    {
                        toolStrip.Items["Eliminar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.New:
                    {
                        toolStrip.Items["Nuevo"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Clear:
                    {
                        toolStrip.Items["Limpiar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Edit:
                    {
                        toolStrip.Items["Editar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Search:
                    {
                        toolStrip.Items["Buscar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Print:
                    {
                        toolStrip.Items["Imprimir"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Approve:
                    {
                        toolStrip.Items["Finalizar"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.Close:
                    {
                        toolStrip.Items["Salir"].Enabled = enabled;
                        break;
                    }
                case ToolBarButtons.InProcess:
                    {
                        toolStrip.Items["En Proceso"].Enabled = enabled;
                        break;
                    }
            }

        }

        public static void ConfigureToolBar(ToolStrip toolStrip, ToolBarButtons buttons)
        {
            toolStrip.Items.Clear();

            if (ContainsButton(buttons, ToolBarButtons.New))
                AddToolStripButton(toolStrip, ToolBarButtons.New);

            if (ContainsButton(buttons, ToolBarButtons.Clear))
                AddToolStripButton(toolStrip, ToolBarButtons.Clear);

            if (ContainsButton(buttons, ToolBarButtons.Save))
                AddToolStripButton(toolStrip, ToolBarButtons.Save);

            if (ContainsButton(buttons, ToolBarButtons.Delete))
                AddToolStripButton(toolStrip, ToolBarButtons.Delete);

            if (ContainsButton(buttons, ToolBarButtons.Edit))
                AddToolStripButton(toolStrip, ToolBarButtons.Edit);

            if (ContainsButton(buttons, ToolBarButtons.Search))
            {
                AddToolStripSeparator(toolStrip);
                AddToolStripButton(toolStrip, ToolBarButtons.Search);
                AddToolStripSeparator(toolStrip);
            }

            if (ContainsButton(buttons, ToolBarButtons.Preview))
                AddToolStripButton(toolStrip, ToolBarButtons.Preview);

            if (ContainsButton(buttons, ToolBarButtons.Print))
            {
                if (toolStrip.Items.Count > 0 && toolStrip.Items[toolStrip.Items.Count - 1].CanSelect)
                    AddToolStripSeparator(toolStrip);
                AddToolStripButton(toolStrip, ToolBarButtons.Print);
                AddToolStripSeparator(toolStrip);
            }

            if (ContainsButton(buttons, ToolBarButtons.Approve))
            {
                if (toolStrip.Items[toolStrip.Items.Count - 1].CanSelect)
                    AddToolStripSeparator(toolStrip);

                AddToolStripButton(toolStrip, ToolBarButtons.Approve);
                AddToolStripSeparator(toolStrip);
            }
            if (ContainsButton(buttons, ToolBarButtons.InProcess))
            {
                if (toolStrip.Items[toolStrip.Items.Count - 1].CanSelect)
                    AddToolStripSeparator(toolStrip);

                AddToolStripButton(toolStrip, ToolBarButtons.InProcess);
                AddToolStripSeparator(toolStrip);
            }

            if (toolStrip.Items.Count > 0 && toolStrip.Items[toolStrip.Items.Count - 1].CanSelect)
                AddToolStripSeparator(toolStrip);

            AddToolStripButton(toolStrip, ToolBarButtons.Close);
        }

        public void ClearControls(Control.ControlCollection controls)
        {
            foreach (Control ctr in controls)
            {
                if (ctr is TextBox || ctr is NumericTextBox)
                    ctr.Text = "";

                else if (ctr is Label)
                {
                    if (ctr.Tag != null)
                        ctr.Text = ctr.Tag.ToString();
                }
                else if (ctr is ComboBox)
                {
                    var combo = (ComboBox)ctr;
                    combo.SelectedIndex = -1;
                    combo.SelectedIndex = -1;
                }
                else if (ctr is DateTimePicker)
                    ((DateTimePicker)ctr).Value = DateTime.Now;

                else if (ctr is CheckBox)
                    ((CheckBox)ctr).Checked = false;

                else if (ctr is TriStateTreeView)
                {
                    var tree = (TriStateTreeView)ctr;
                    tree.SetChecked(tree.TopNode, SIL.FieldWorks.Common.Controls.TriStateTreeView.CheckState.Unchecked);
                }
                else if (ctr is CheckedListBox)
                {
                    var list = (CheckedListBox)ctr;
                    for (var i = 0; i < list.Items.Count; i++)
                        list.SetItemChecked(i, false);
                }

                if (ctr.Controls.Count > 0)
                    ClearControls(ctr.Controls);
            }
        }

        public static void DisplayError(string title)
        {
            DisplayError(title, false);
        }

        public static void DisplayError(string title, bool end)
        {
            new ErrorForm(title).ShowDialog();
            if (end)
                Environment.Exit(0);
        }

        public static void DisplayError(string title, Exception ex)
        {
            DisplayError(title, ex, false);
        }

        public static void DisplayError(string title, Exception ex, bool end)
        {
            new ErrorForm(title, ex).ShowDialog();
            if (end)
                Environment.Exit(0);
        }

        public static bool ValidPhoneChar(char value)
        {
            var allowedList = "0123456789-()" + Keys.Back;
            return allowedList.IndexOf(value) > -1;
        }

        public static string MonthName(int monthNumber)
        {
            string result = "";
            switch (monthNumber)
            {
                case 1:
                    result = "Enero";
                    break;
                case 2:
                    result = "Febrero";
                    break;
                case 3:
                    result = "Marzo";
                    break;
                case 4:
                    result = "Abril";
                    break;
                case 5:
                    result = "Mayo";
                    break;
                case 6:
                    result = "Junio";
                    break;
                case 7:
                    result = "Julio";
                    break;
                case 8:
                    result = "Agosto";
                    break;
                case 9:
                    result = "Setiembre";
                    break;
                case 10:
                    result = "Octubre";
                    break;
                case 11:
                    result = "Noviembre";
                    break;
                case 12:
                    result = "Diciembre";
                    break;
            }
            return result;
        }

        public static bool CorreoValido(string correo)
        {
            return correo.IndexOf("@") > 0 && correo.LastIndexOf(".") > correo.IndexOf("@") && correo.Length > 3;
        }

        public void ShowError(string description)
        {
            MessageBox.Show(description, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public bool ShowQuestion(string description)
        {
            return (MessageBox.Show(description, Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes);
        }

        public void ShowConfirmation(string description)
        {
            MessageBox.Show(description, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        protected void ShowScreen(Form form)
        {
            form.MdiParent = MdiParent;
            ActivateMdiChild(form);
            form.Show();
        }

        protected static void PopulateStatusComboBox(ComboBox comboBox)
        {
            PopulateComboBox(BCOT.GetEstados(), comboBox, true);
        }

        public static void CloneDataRow(object source, object target)
        {
            var type = source.GetType();
            foreach (var property in type.GetProperties())
            {
                if (IsFieldValid(property) && !IsFieldNull(property.Name, source))
                {
                    var value = property.GetValue(source, null);
                    property.SetValue(target, value, null);
                }
            }
        }

        public static void CloneDataTable(DataTable source, DataTable target)
        {
            target.Clear();
            foreach (DataRow row in source.Rows)
            {
                var newRow = target.NewRow();
                CloneDataRow(row, newRow);
                target.Rows.Add(newRow);
            }
        }

        public static void FormatNumbers(UltraGridBase grid)
        {
            foreach(var col in grid.DisplayLayout.Bands[0].Columns)
            {
                if (col.DataType.Name == "Decimal")
                {
                    col.Format = "#,##0.00";
                }
            }
        }

        #endregion

        #region Methods: Private

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nombre")]
        protected static string GetEstadoNombre(IEnumerable<BEEntity> list, string id)
        {

            foreach (var item in list)
            {
                if (item.Id.Equals(id))
                    return item.Nombre;
            }
            return "";
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "nombre"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nombre")]
        protected static string GetEstadoIdByNombre(IEnumerable<BEEntity> list, string nombre)
        {
            string nombreLower = nombre.ToLower();
            foreach (var item in list)
            {
                if (item.Nombre.ToLower().Equals(nombreLower))
                    return item.Id;
            }
            return "";
        }

        private static bool IsFieldValid(PropertyInfo property)
        {
            return (property.Name != "Id"
                    && !property.Name.EndsWith("Row")
                    && property.CanRead
                    && property.CanWrite
                    && property.GetIndexParameters().Length == 0
                    );
        }

        private static bool IsFieldNull(string propertyName, object obj)
        {
            var methodName = "Is" + propertyName + "Null";
            var method = obj.GetType().GetMethod(methodName);
            if (method != null)
                return (bool)method.Invoke(obj, null);
            return false;
        }

        private static bool ContainsButton(ToolBarButtons combined, ToolBarButtons checkagainst)
        {
            return ((combined & checkagainst) == checkagainst);
        }

        private static void AddToolStripButton(ToolStrip toolStrip, ToolBarButtons buttonType)
        {
            var newButton = new ToolStripButton();
            string imageName = "", text = "";

            switch (buttonType)
            {
                case ToolBarButtons.Save:
                    {
                        text = "Guardar";
                        imageName = NamespaceName + ".Images.tb_save.png";
                        break;
                    }
                case ToolBarButtons.Delete:
                    {
                        text = "Eliminar";
                        imageName = NamespaceName + ".Images.tb_delete.png";
                        break;
                    }
                case ToolBarButtons.New:
                    {
                        text = "Nuevo";
                        imageName = NamespaceName + ".Images.tb_add.png";
                        break;
                    }
                case ToolBarButtons.Clear:
                    {
                        text = "Limpiar";
                        imageName = NamespaceName + ".Images.tb_new.png";
                        break;
                    }
                case ToolBarButtons.Edit:
                    {
                        text = "Editar";
                        imageName = NamespaceName + ".Images.tb_edit.png";
                        break;
                    }
                case ToolBarButtons.Preview:
                    {
                        text = "Ver Reporte";
                        imageName = NamespaceName + ".Images.tb_preview.png";
                        break;
                    }
                case ToolBarButtons.Search:
                    {
                        text = "Buscar";
                        imageName = NamespaceName + ".Images.tb_search.png";
                        break;
                    }
                case ToolBarButtons.Print:
                    {
                        text = "Imprimir";
                        imageName = NamespaceName + ".Images.tb_print.png";
                        break;
                    }
                case ToolBarButtons.Approve:
                    {
                        text = "Finalizar";
                        imageName = NamespaceName + ".Images.tb_apply.png";
                        break;
                    }
                case ToolBarButtons.InProcess:
                    {
                        text = "En Proceso";
                        imageName = NamespaceName + ".Images.tb_apply.png";
                        break;
                    }
                case ToolBarButtons.Close:
                    {
                        text = "Salir";
                        imageName = NamespaceName + ".Images.tb_close.png";
                        break;
                    }
            }

            // Lee imagen de los resources del assembly
            imageStream = assembly.GetManifestResourceStream(imageName);
            newButton.Text = text;
            newButton.Name = text;
            if (imageStream != null)
                newButton.Image = Image.FromStream(imageStream);
            newButton.TextAlign = ContentAlignment.BottomCenter;
            newButton.TextImageRelation = TextImageRelation.ImageAboveText;
            newButton.ImageScaling = ToolStripItemImageScaling.SizeToFit;
            newButton.AutoSize = true;
            newButton.Tag = buttonType;

            toolStrip.Items.Add(newButton);
        }

        private static void AddToolStripSeparator(ToolStrip toolStrip)
        {
            var separator = new ToolStripSeparator {Tag = ToolBarButtons.None};
            toolStrip.Items.Add(separator);
        }

        private static void PopulateComboBox(IEnumerable<BEEntity> list, ComboBox combobox, bool allItem)
        {
            combobox.BeginUpdate();
            combobox.Items.Clear();
            if (allItem)
                combobox.Items.Add(new BEEntity { Id = "", Nombre = "[Todos]" });

            foreach (var item in list)
                combobox.Items.Add(item);

            combobox.ValueMember = "Id";
            combobox.DisplayMember = "Nombre";
            combobox.SelectedIndex = 0;
            combobox.EndUpdate();
        }

        #endregion
    }
}
